查看原文
其他

基于Matlab自动测量电击阈值的Shock Work-up/Calibration 程序

张志伟,念靖晴 流浪心球 2022-04-26
第一部分 背景

本程序是基于Matlab平台实现多通道电刺激仪的电击阈值自动化测定。关于该电刺激仪的详细介绍和E-prime中的Shock work-up的实现可查阅:多通道电刺激仪安装与使用说明(含E-prime实例),此部分内容在本推文中我们将不在进行赘述。

本程序的主要流程如上图所示,首先呈现一个注视点500 ms,之后呈现一个闪电(2000 ms),在闪电出现的同时给被试一个电击(初始值为 250 μA),电击结束后,呈现评分界面,被试通过输入相应的分数(0~10分),进行判断,被试输入评分后界面消失。记录被试的评分数值,如果评分等于8,则记录当前的电击强度值,以及评分值。如果评分小于8,则需要进行新一轮的试次。新一轮试次的电击强度值等于被试评分小于8的电击强度值加上250。直到评分等于8。需记录每一次电击强度值和评分值。如果评分大于8,则需要进行新一轮的试次。新一轮试次的电击强度值等于被试评分大于8的电击强度值减去250。直到评分等于8。需记录每一次电击强度值和评分值。


 当被试的评分等于8时,则进入新的一轮电击强度阈值测定。被试评分等于8的这个过程需要重复3次,重复3次之后,需报告3次电击强度的平均值,并在结果中进行记录。


第二部分 核心代码解读


为了方便读者进一步使用和修改代码,我们对此部分代码进行公开,但由于个人的精力和能力有限,我们也清晰的直到本代码仍有可以进行进一步优化。因此我们也希望各位大神们给代码的优化提出宝贵的修改建议或示例 [期待各位大神的赐教和版本轰炸!!!],从而让Shock Work-up/Calibration这个过程更科学和规范,从而提升相关研究的效率。

为了便于大家测试,我们已经对源码进行了打包并上传到了OSF平台,查阅和下载链接为:https://osf.io/m3p8q/ 或 点击文末"阅读原文"可直接跳转。

%% shock workup procedure% The code was adequate for a multichannel stimulator (SXC-4A, Sanxia Technique Inc., China). % The code made by Zhiwei Zhang[E-mail:760861993@qq.com]. Modified by Jingqing Nian[E-mail:nianjingqing@126.com].% School of Psychology,Guizhou Normal University% The materials have a Creative Commons CC BY license so that you can use them in any way you want.% You just need to provide an attribution (“by Zhiwei Zhang & Jingqing Nian”,DOI:10.17605/OSF.IO/M3P8Q).

%% Close all & Clear Commandclose all;clear;clc;
%% Serial port
%判段是否有串口正在使用,如有删除所有串口设备
if ~isempty(instrfind) delete(instrfindall); pause(8); end
%获取当前可用串口信息Ports = instrhwinfo('serial');
%获取可用串口端号dd = Ports.AvailableSerialPorts;
%定义串口并设置参数,一代波特率为 9600;二代波特率为 115200,理论上从串口发命令到仪器开始输出刺激的时间间隔约为 2msscom=serial(dd{3},'BaudRate',9600,'Parity','none','DataBits',8,'StopBits',1);
%打开端口fopen(scom);
%重置4个通道参数fprintf(scom,'%s','$A1R;c1234;#'); pause(0.5);%暂停0.5s%% Subject Information
%注视点的大小和位置可根据需要进行微调%程序运行完成后检查被试序号是否正确保存即可%这里选择的评分键位为数字键1到0,分别代表1-10分,0分为 、~ 键%收集被试信息
prompt = {'被试编号','被试性别[1=男,2=女]','年级','被试年龄','被试优势手[1=左手,2=右手]'};dlg_title = '被试信息'; %被试的各种信息num_line = 1;defautanswer = {'','','','',''}; %默认信息subinfo= inputdlg(prompt,dlg_title,num_line,defautanswer);
%% 打开屏幕%Screen('Preference', 'ConserveVRAM', 64)
Screen('Preference', 'SkipSyncTests', 1)[w,wsize]=Screen('Openwindow',0,[],[]);
%% 电击参数初始值
ndjz=250; % 初始电击值Step_Size = 250; % 定义步长
%% 注视点Screen('TextSize',w,200);%注视点大小
%%坐标cx=wsize(3)/2;cy=wsize(4)/2;

cs=0;%cs为评分为8的次数
%% 导入图片kaishi=imread('.\materials\Ins01010.bmp');shandian=imread('.\materials\T1.bmp');fankui=imread('.\materials\Ins03.bmp');
%% 定义键盘
KbName('UnifyKeyNames');[~,~,keycode]=KbCheck;startkey=KbName('q');fb0=192;fb1=49;fb2=50;fb3=51;fb4=52;fb5=53;fb6=54;fb7=55;fb8=56;fb9=57;fb10=48;

%% 指导语tex=Screen('MakeTexture',w,kaishi);Screen('DrawTexture',w,tex);Screen(w,'Flip');

while true [~,~,keycode]=KbCheck; if keycode(startkey) WaitSecs(1); break end end

tiaojian=1;i=1;%i为trial数量%result为被试行为记录,trial表示第几个试次,djz表示电击大小,pf为反馈评分,zong3为三个评分为8的电击值result.trial=[];result.djz=[];result.pf=[];zong3=[];

cdjz=ndjz;while tiaojian %% 注视点 Screen('DrawDots',w,[cx-50,cy-90],50,[0 0 0],[],[1]); Screen(w,'Flip'); WaitSecs(0.5); sdjz=strcat('i',num2str(cdjz)); %% 电击 tex=Screen('MakeTexture',w,shandian); Screen('DrawTexture',w,tex); Screen(w,'Flip'); fprintf(scom,'%s',['$A1S;c2;w3;f100;p2000;o1;r10;' sdjz ';#']); % 预设电刺激仪通道参数 % 协议符:$-起始符; #-终止符 % 机器码:A1 % 协议命令:S-设置参数;R-重置参数;T-触发电刺激;P-刺激序列暂停 % 通道号:c, c1~c4表示1~4个通道 % 波形:w, w1-恒流,w2-正弦波,w3-方波,w4-三角波 % 频率:f,1~100 Hz % 脉宽:p, 50~9950 μs % 方向:o1-正向; o2-反向 % 持续时间:恒流- t+数字,表示持续多少 ms; te 表示一直输出 % 非恒流-r+数字,表示循环多少次;re 表示持续输出 % 电流强度:i+数字(5~9995)μA pause(0.5);%暂停0.5s fprintf(scom,'%s',['$A1T;c2;#']); %触发指定通道 WaitSecs(2); result(i).trial=i; result(i).djz=cdjz; %% 评分 tex=Screen('MakeTexture',w,fankui); Screen('DrawTexture',w,tex); Screen(w,'Flip'); WaitSecs(0.3);%为了被试不要乱按,加了限定时间 while true [~,~,keycode]=KbCheck; if keycode(192) result(i).pf=0; cdjz=cdjz+Step_Size; break elseif keycode(49) result(i).pf=1; cdjz=cdjz+Step_Size; break elseif keycode(50) result(i).pf=2; cdjz=cdjz+Step_Size; break elseif keycode(51) result(i).pf=3; cdjz=cdjz+Step_Size; break elseif keycode(52) result(i).pf=4; cdjz=cdjz+Step_Size; break elseif keycode(53) result(i).pf=5; cdjz=cdjz+Step_Size; break elseif keycode(54) result(i).pf=6; cdjz=cdjz+Step_Size; break elseif keycode(55) result(i).pf=7; cdjz=cdjz+Step_Size; break elseif keycode(56) cs=cs+1; result(i).pf=8; zong3=[cdjz,zong3]; cdjz=ndjz; break elseif keycode(57) result(i).pf=9; cdjz=cdjz-Step_Size; break elseif keycode(48) result(i).pf=10; cdjz=cdjz-Step_Size; break elseif keycode(27) sca break end end if cs==3 tiaojian=0; break end i=i+1; endavg=mean(zong3);result(1).avg=avg;%代表三个评分为8的电击值的平均
Screen('DrawText',w,double('实验结束'),cx-50,cy-90);Screen(w,'Flip');WaitSecs(1);
fclose(scom);%关闭串口设备对象delete(scom);%删除内存中的串口设备对象clear scom; %清除工作空间中的串口设备对象

sca
bs=strcat('bs',cell2mat(subinfo(1)));uisave({'result'},bs);


*如遇链接失效,可后台联系小编处理。若有实验程序编制需求也可以后台留言。



==流浪心球 精品推荐==
ERP数据分析入门指导课程:
01 ERP基础知识 || 02 常见的ERP成分 || 03 ERP的产生和溯源过程 || 04 ERP的优势 || 05 ERP的核心背景知识 || 06 ERP记录与分析方法 || 07 ERP研究的评估

ERP数据分析高阶进击:
ERP数据质量检测新指标(SME)网络研讨会笔记
SME:ERP数据质量检测的新指标 || 视频资源 
标准测量误差(SME):ERP研究中数据质量评估的通用指标
基于Matlab、EEGLab和ERPlab的偏侧化差异波(N2pc/Pd/CDA )成分分析方法
代码篇 || 基于Matlab、EEGLab和ERPlab的偏侧化差异波成分分析
EEG数据分析时如何对分段数据进行伪迹检测与排除?
ERP数据分析中N2pc/Pd成分置换检验的实现
ERP分析中如何自动删除休息阶段的脑电数据?
ADAM:EEG/MEG多元统计分析工具包
基于Python+MNE的偏侧化差异波(N2pc/Pd/CDA )成分分析方法

EEG/ERP研究中避坑指南:
EEG/ERP研究中如何获得稳定可信的结果或效应
采集最佳质量EEG数据的操作流程(1)
在EEG研究中,如何降低COVID-19的传播风险?
脑电数据分析中如何获取相对干净的数据结果?
EEG神经振荡分析:已公开数据及代码共享
ERP CORE:事件相关电位研究的开放资源
 
科研利器
功效等值线:心理学研究中样本量和精度的优化
心理学脑电研究方法探讨 | 中国社会科学报
轻松获取并添加文章发表期刊的封面、目录和封底

EEG实验中Matlab并口数据位发送和接收的实现方法

攻克心理学研究中文献查阅的七大难关

心理学实验常用编程软件和学习资源汇总

基于SHINE toolbox的图片标准化教程

EEG/ERP学习资源汇总

EEG等电生理数据开放共享合集

【荐书】EEG/ERP书籍(海外篇)

tDCS等神经调控技术书籍资源荐读


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存